package com.zhq.okhttp.subscribe;

import android.content.Context;

import com.alibaba.fastjson.JSON;
import com.zhq.apputil.utils.LogUtil;
import com.zhq.apputil.utils.StringUtil;
import com.zhq.constant.AppConstant;
import com.zhq.okhttp.RxApiManager;
import com.zhq.okhttp.bean.HttpBeanResponse;
import com.zhq.okhttp.progress.ProgressCancelListener;
import com.zhq.okhttp.progress.ProgressDialogHandler;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.ConnectException;
import java.net.SocketTimeoutException;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import okhttp3.ResponseBody;
import retrofit2.HttpException;


/**
 * 用于在Http请求开始时，自动显示一个ProgressDialog
 * 在Http请求结束是，关闭ProgressDialog
 * 调用者自己对请求数据进行处理
 */
public class ProgressSubscriber implements Observer<ResponseBody>, ProgressCancelListener {
    private static final String TAG = ProgressSubscriber.class.getSimpleName();
    private ProgressDialogHandler mProgressDialogHandler;
    private HttpRequestListener listener;
    private String message, tag;
    private Disposable disposable;

    public ProgressSubscriber(Builder builder) {
        this.listener = builder.onListener;
        this.message = builder.message;
        RxApiManager.get().add(listener);
        if (builder.softReference.get() != null) {
            mProgressDialogHandler = new ProgressDialogHandler(builder.softReference.get(), this, builder.message, true);
        }
    }

    private void showProgressDialog() {
        if (mProgressDialogHandler != null) {
            mProgressDialogHandler.obtainMessage(ProgressDialogHandler.SHOW_PROGRESS_DIALOG).sendToTarget();
        }
    }

    private void dismissProgressDialog() {
        if (mProgressDialogHandler != null) {
            mProgressDialogHandler.obtainMessage(ProgressDialogHandler.DISMISS_PROGRESS_DIALOG).sendToTarget();
            mProgressDialogHandler = null;
        }
    }

    /**
     * 对错误进行统一处理
     * 隐藏ProgressDialog
     *
     * @param e
     */
    @Override
    public void onError(Throwable e) {
        LogUtil.e(TAG, "error:" + e.getLocalizedMessage());
        if (listener != null) {
            String msg = e.getLocalizedMessage();
            if (e instanceof SocketTimeoutException) {
                msg = "连接网络超时，请检查您的网络状态";
            } else if (e instanceof ConnectException) {
                msg = "网络中断，请检查您的网络状态";
            } else if (e instanceof HttpException) {
                msg = e.getMessage();
                HttpException httpException = (HttpException) e;
                int code = httpException.code();
                msg = httpException.getMessage();
                LogUtil.e("code:" + code);
                if (code == AppConstant.HttpResponse.NETWORK_CONNECT_TIME_OUT) {
                    msg = "网络不给力";
                }
            }
            removeDisposable();
            dismissProgressDialog();
            listener.requestFailure(msg);
        }
    }

    /**
     * 完成，隐藏ProgressDialog
     */
    @Override
    public void onComplete() {
        removeDisposable();
        dismissProgressDialog();
    }

    /**
     * 订阅开始时调用
     * 显示ProgressDialog
     */
    @Override
    public void onSubscribe(Disposable d) {
        disposable = d;
        showProgressDialog();
    }

    /**
     * 将onNext方法中的返回结果交给Activity或Fragment自己处理
     */
    @Override
    public void onNext(ResponseBody response) {
        if (listener != null) {
            try {
                String data = response.string();
                HttpBeanResponse beanResponse = JSON.parseObject(data, HttpBeanResponse.class);
                if (beanResponse.getStatusCode() == AppConstant.HttpResponse.SUCCESS && beanResponse.isSuccess()) {
                    listener.requestSuccess(beanResponse.getData());
                } else {
                    if(!StringUtil.isEmpty(beanResponse.getMessage())){
                        listener.requestErrorType(beanResponse.getMessage(), beanResponse.getStatusCode());
                    }
                }
            } catch (IOException e) {//解析异常以及IO异常
                listener.requestErrorType("数据出错", AppConstant.HttpResponse.DATA_PARSE_ERROR);
            }
        } else {
            removeDisposable();
        }

    }

    /**
     * 取消ProgressDialog的时候，取消对observable的订阅，同时也取消了http请求
     */
    @Override
    public void onCancelProgress() {
        removeDisposable();
    }

    /**
     * 销毁disposable
     */
    private void removeDisposable() {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
            disposable = null;
        }
    }


    public static class Builder {
        private HttpRequestListener onListener;
        private String message;
        private String tag;
        private WeakReference<Context> softReference;

        public Builder(Context mContext) {
            this.softReference = new WeakReference<>(mContext);
        }

        public Builder setMessage(String message) {
            this.message = message;
            return this;
        }

        public Builder setTag(String tag) {
            this.tag = tag;
            return this;
        }

        public Builder setHttpRequestOnListener(HttpRequestListener onListener) {
            this.onListener = onListener;
            return this;
        }

        public ProgressSubscriber build() {
            return new ProgressSubscriber(this);
        }
    }

}